Skip to content

Conversation

@nikosdouvlis
Copy link
Member

@nikosdouvlis nikosdouvlis commented Jan 20, 2026

Description

Why:
Safari's Intelligent Tracking Prevention (ITP) caps cookies set via fetch/XHR
to 7 days. When users switched from redirectUrl to the navigate callback pattern,
the existing ITP workaround (via /v1/client/touch endpoint) stopped working
because the touch endpoint logic only ran in the redirectUrl branch.

What changed:

  • Added decorateUrl function to the navigate callback that wraps URLs with the
    touch endpoint when Safari ITP fix is needed (client.isEligibleForTouch())
  • Updated SetActiveNavigate type signature to include decorateUrl parameter
  • Added dev-mode warning when decorateUrl is not called but ITP fix is needed
  • Updated all internal usages in SignIn, SignUp, and SessionTasks components
    to pass decorateUrl through navigateOnSetActive

Context:
The decorateUrl may return an external URL (https://...) when ITP fix is needed,
requiring window.location.href instead of client-side navigation. This pattern
is documented in the type definitions.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Added URL-decoration support for post-auth navigation; callers receive a decorateUrl callback to wrap destinations. Decorated external URLs may trigger full-page navigation to refresh cookies under Safari ITP.
  • Tests

    • Added integration tests simulating Safari ITP cookie expiry and touch flows.
    • Added unit tests validating decorateUrl behavior and navigation wrapping.

✏️ Tip: You can customize this high-level summary in your review settings.

…ack for Safari ITP fix

Why:
Safari's Intelligent Tracking Prevention (ITP) caps cookies set via fetch/XHR
to 7 days. When users switched from redirectUrl to the navigate callback pattern,
the existing ITP workaround (via /v1/client/touch endpoint) stopped working
because the touch endpoint logic only ran in the redirectUrl branch.

What changed:
- Added decorateUrl function to the navigate callback that wraps URLs with the
  touch endpoint when Safari ITP fix is needed (client.isEligibleForTouch())
- Updated SetActiveNavigate type signature to include decorateUrl parameter
- Added dev-mode warning when decorateUrl is not called but ITP fix is needed
- Updated all internal usages in SignIn, SignUp, and SessionTasks components
  to pass decorateUrl through navigateOnSetActive

Context:
The decorateUrl may return an external URL (https://...) when ITP fix is needed,
requiring window.location.href instead of client-side navigation. This pattern
is documented in the type definitions.
Why:
The Safari ITP fix (decorateUrl in setActive) was added without integration
test coverage. These tests ensure the touch endpoint navigation works correctly
when the client cookie is close to expiration.

What changed:
- Added 4 tests covering the Safari ITP workaround flow
- Tests verify touch endpoint is called when cookie expires within 8 days
- Tests verify decorateUrl behavior with mocked isEligibleForTouch
@changeset-bot
Copy link

changeset-bot bot commented Jan 20, 2026

🦋 Changeset detected

Latest commit: c199933

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 20 packages
Name Type
@clerk/clerk-js Minor
@clerk/shared Minor
@clerk/ui Minor
@clerk/chrome-extension Patch
@clerk/expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/msw Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/react Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/vue Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Jan 29, 2026 0:08am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

📝 Walkthrough

Walkthrough

Introduces a DecorateUrl callback into Clerk's setActive navigation flow and a public DecorateUrl type. Propagates decorateUrl through core clerk logic, shared types, SignIn/SignUp/SessionTasks contexts, and UI components. Runtime behavior: when eligible for Safari ITP touch, decorateUrl can wrap redirect URLs using the /v1/client/touch flow and may trigger full-page navigation for absolute decorated URLs. Adds unit tests and an integration Playwright suite simulating Safari ITP cookie scenarios.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main feature: adding Safari ITP decorateUrl workaround to setActive, accurately reflecting the core change across clerk-js, ui, and shared packages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 20, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7623

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7623

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7623

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7623

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7623

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7623

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@7623

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7623

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7623

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7623

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7623

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7623

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7623

@clerk/react

npm i https://pkg.pr.new/@clerk/react@7623

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7623

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7623

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7623

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7623

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7623

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7623

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7623

commit: c199933

Copy link
Member

@brkalow brkalow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks good! Does the warning fire reliably? I suppose yes, we're mostly safe because Clerk doesn't unmount / get cleaned up on navigations, unless it's a full navigation.

'Clerk: The navigate callback in setActive() did not call decorateUrl(). ' +
'In Safari, sessions may be limited to 7 days due to Intelligent Tracking Prevention (ITP). ' +
'Use decorateUrl() to wrap your destination URL to enable the ITP workaround. ' +
'Learn more: https://clerk.com/docs/troubleshooting/safari-itp',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙃 this link leads to 404

# Conflicts:
#	packages/ui/src/components/SignIn/handleCombinedFlowTransfer.ts
Why:
The previous check `decoratedUrl.startsWith('https://')` incorrectly triggered full page navigation for any absolute https:// redirect URL, even when decorateUrl didn't modify it. This caused unnecessary full page navigations in non-ITP scenarios.

What changed:
Now checks if decorateUrl actually modified the URL (`decoratedUrl !== redirectUrl`) AND that the result is an absolute http/https URL. This ensures full page navigation only happens when Safari ITP decoration is applied.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants